import { Box3, Vector3 } from 'three-legacy';

/**
 * 获取Box3 8个顶点的坐标
 * @param box Box3对象
 * @returns 8个顶点坐标数组
 */
export function getCornerPoints(box: Box3) {
  const low = box.min;
  const high = box.max;
  const corner1 = new Vector3(low.x, low.y, low.z);
  const corner2 = new Vector3(high.x, low.y, low.z);
  const corner3 = new Vector3(low.x, high.y, low.z);
  const corner4 = new Vector3(low.x, low.y, high.z);

  const corner5 = new Vector3(high.x, high.y, low.z);
  const corner6 = new Vector3(high.x, low.y, high.z);
  const corner7 = new Vector3(low.x, high.y, high.z);
  const corner8 = new Vector3(high.x, high.y, high.z);
  return [
    corner1,
    corner2,
    corner3,
    corner4,
    corner5,
    corner6,
    corner7,
    corner8,
  ];
}

/**
 * 计算在向量方向上，pointer 到center 的最大和最小距离
 * @param normal 向量
 * @param center 中心点
 * @param pointer 包围盒顶点数组
 * @returns 最小最大距离
 */
export function getMinMaxDistance(
  normal: Vector3,
  center: Vector3,
  pointer: Vector3[],
) {
  let min = Infinity,
    max = -Infinity;
  for (const point of pointer) {
    const p = new Vector3();
    p.copy(point);
    const distance = normal.dot(new Vector3().subVectors(p, center));
    if (distance < min) {
      min = distance;
    }
    if (distance > max) {
      max = distance;
    }
  }
  return { min, max };
}

/**
 * 绘制箭头
 * @param arrowStart 开始点
 * @param arrowEnd 结束点
 * @param arrowWidth 箭头宽度
 * @param arrowHeadLength 箭头长度，负数箭头向外，正数箭头向内
 * @param planeDirection 箭头面的朝向
 */
export const drawTriangular = (
  arrowStart: Vector3,
  arrowEnd: Vector3,
  arrowWidth: number,
  arrowHeadLength: number,
  planeDirection: Vector3,
) => {
  // 计算箭头方向和基准点
  const arrowDirection = new Vector3()
    .subVectors(arrowEnd, arrowStart) // 将该向量设置为 箭头起点 - 箭头的顶点
    .normalize(); // 将该向量转换为单位向量（unit vector）， 也就是说，将该向量的方向设置为和原向量相同，但是其长度（length）为1。
  const perpendicular1 = new Vector3()
    .crossVectors(arrowDirection, planeDirection) // 将该向量设置为传入的a与b的叉积
    .normalize()
    .multiplyScalar(arrowWidth); // 将该向量与所传入的标量（三角形宽度）进行相乘。
  const perpendicular2 = new Vector3()
    .crossVectors(arrowDirection, perpendicular1) // 将该向量设置为传入的a与b的叉积
    .normalize()
    .multiplyScalar(arrowWidth); // 将该向量与所传入的标量（三角形宽度）进行相乘。

  // 定义箭头头部六个顶点的位置
  const baseCenter = arrowEnd.clone().add(
    arrowDirection.clone().multiplyScalar(Math.sqrt(2) * (arrowHeadLength / 8)),
    // .multiplyScalar(arrowHeadLength),
  );
  const vertex1 = baseCenter.clone().add(perpendicular1);
  const vertex2 = baseCenter.clone().sub(perpendicular2); // 从该向量减去向量v Z
  const vertex3 = baseCenter.clone().sub(perpendicular1); // 将传入的向量v和这个向量相加。
  const vertex4 = baseCenter.clone().add(perpendicular2);
  const allVertex = [arrowEnd, vertex1, vertex2, vertex3, vertex4, arrowStart];
  // 定义箭头头部的线段  围绕顶点进行绘制四条线，0是顶点，1，2，3，4分别是对应四个点。
  // 1，2，3，4分别是对应四个点,绘制底部的四边形
  const indices = [0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2, 3, 3, 4, 4, 1, 0, 5];
  // 是面片、线或点几何体的有效表述。包括顶点位置，面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。
  // 使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销。
  return indices.map((index) => allVertex[index]);
};
// 计算两点之间x,y,z 三个方向的距离
export function getXYZDistance(pointA: number[], pointB: number[]) {
  // 计算x、y、z方向上的距离差
  const x = pointB[0] - pointA[0];
  const y = pointB[1] - pointA[1];
  const z = pointB[2] - pointA[2];
  return { x, y, z };
}
//三维空间 三个点坐标确定圆心坐标
export function getCircleCenter(A: Vector3, B: Vector3, C: Vector3) {
  const a = B.clone().sub(A);
  const b = C.clone().sub(A);
  const c = A.clone().sub(B);

  const aSq = a.lengthSq();
  const bSq = b.lengthSq();
  const cSq = c.lengthSq();

  const x = (A.x * aSq + B.x * bSq + C.x * cSq) / (aSq + bSq + cSq);
  const y = (A.y * aSq + B.y * bSq + C.y * cSq) / (aSq + bSq + cSq);
  const z = (A.z * aSq + B.z * bSq + C.z * cSq) / (aSq + bSq + cSq);

  return [x, y, z];
}
